﻿@namespace Microsoft.FluentUI.AspNetCore.Components
@inherits ListComponentBase<TOption>
@typeparam TOption

<CascadingValue Value="@_internalListContext" Name="ListContext" TValue="InternalListContext<TOption>" IsFixed=true>
    <div class="@ClassValue fluent-autocomplete-multiselect"
         style="@StyleValue"
         @attributes="AdditionalAttributes"
         auto-height="@(!string.IsNullOrEmpty(MaxAutoHeight))">
        <FluentKeyCode Anchor="@Id" OnKeyDown="@KeyDownHandlerAsync" Only="@CatchOnly" PreventDefaultOnly="@PreventOnly" />

        <FluentTextField role="combobox"
                         @ref="@Element"
                         Id="@Id"
                         Name="@Name"
                         Embedded="true"
                         Required="@Required"
                         AutoComplete="@AutoComplete"
                         Appearance="@Appearance"
                         Disabled="@Disabled"
                         ReadOnly="@ReadOnly"
                         Label="@Label"
                         LabelTemplate="@LabelTemplate"
                         Placeholder="@(SelectedOptions?.Any() is false ? Placeholder : string.Empty)"
                         aria-expanded="@(IsMultiSelectOpened ? "true" : "false")"
                         aria-controls="@(IsMultiSelectOpened ? IdPopup : string.Empty)"
                         aria-label="@GetAutocompleteAriaLabel()"
                         Value="@ValueText"
                         @onclick="@OnDropDownExpandedAsync"
                         @oninput="@InputHandlerAsync"
                         autofocus="@Autofocus"
                         Style="@ComponentWidth">
            @* Selected Items *@
            @if (this.SelectedOptions?.Any() == true)
            {
                @* Normal (single) line height *@
                if (string.IsNullOrEmpty(MaxAutoHeight))
                {
                    <fluent-horizontal-scroll id="@IdScroll" style="width: 100%;" slot="start">
                        <fluent-flipper onclick="event.stopPropagation(); document.getElementById('@IdScroll').scrollToPrevious();"
                                        slot="previous-flipper"
                                        aria-hidden="false"
                                        aria-label="@TitleScrollToPrevious"
                                        title="@TitleScrollToPrevious"
                                        role="button"
                                        tabindex="0"
                                        class="previous fluent-autocomplete-previous"
                                        direction="previous"></fluent-flipper>
                        <fluent-flipper onclick="event.stopPropagation(); document.getElementById('@IdScroll').scrollToNext();"
                                        slot="next-flipper"
                                        aria-hidden="false"
                                        aria-label="@TitleScrollToNext"
                                        title="@TitleScrollToNext"
                                        role="button"
                                        tabindex="0"
                                        class="next fluent-autocomplete-next"
                                        direction="next"></fluent-flipper>
                        @RenderSelectedOptions
                        &nbsp;
                    </fluent-horizontal-scroll>
                }

                @* Auto-height with items wrap *@
                else
                {
                    <div id="@IdScroll" slot="start" class="auto-height" style="@($"max-height: {MaxAutoHeight};")">
                        @RenderSelectedOptions
                    </div>
                }

            }
            @if (!Disabled && !ReadOnly)
            {
                if (this.SelectedOptions?.Any() == true || !string.IsNullOrEmpty(ValueText))
                {
                    if (IconDismiss != null)
                    {
                        <FluentIcon Value="@IconDismiss"
                                    Width="12px"
                                    Style="cursor: pointer;"
                                    Slot="end"
                                    Title="Clear"
                                    @onfocus="@(e => { IsReachedMaxItems = false; IsMultiSelectOpened = false; })"
                                    tabindex="0"
                                    role="button"
                                    OnClick="@OnClearAsync" />
                    }
                }
                else
                {
                    if (IconSearch != null)
                    {
                        <FluentIcon Value="@IconSearch"
                                    Width="16px"
                                    Style="cursor: pointer;"
                                    Slot="end"
                                    Title="Search"
                                    @onfocus="@(e => { IsReachedMaxItems = false; IsMultiSelectOpened = false; })"
                                    tabindex="0"
                                    role="button"
                                    OnClick="@OnDropDownExpandedAsync" />
                    }
                }
            }
        </FluentTextField>

        @* List of available items *@
        @if (IsMultiSelectOpened && (ShowOverlayOnEmptyResults || Items?.Any() == true))
        {
            @if (SelectValueOnTab)
            {
                <FluentKeyCode Anchor="@Id"
                               OnKeyDown="@KeyDownHandlerAsync"
                               Only="@SelectValueOnTabOnly"
                               PreventDefaultOnly="@SelectValueOnTabOnly" />
            }

            <FluentOverlay OnClose="@(e => IsMultiSelectOpened = false)" Visible="true" Transparent="true" FullScreen="true" />
            <FluentAnchoredRegion Anchor="@Id"
                                  HorizontalDefaultPosition="HorizontalPosition.Right"
                                  HorizontalInset="true"
                                  VerticalDefaultPosition="@VerticalPosition.Unset"
                                  Style="margin-top: 10px; border-radius: calc(var(--control-corner-radius) * 2px); background-color: var(--neutral-layer-floating);"
                                  Shadow="ElevationShadow.Flyout">
                @if (HeaderContent != null)
                {
                    @HeaderContent(Items ?? Array.Empty<TOption>())
                }

                <div id="@IdPopup" role="listbox" style="@ListStyleValue" tabindex="0">
                    @if (Items != null)
                    {
                        var selectableItem = GetOptionValue(SelectableItem);

                        @if (Virtualize)
                        {
                            <Virtualize ItemsProvider="LoadFilteredItemsAsync" @ref="VirtualizationContainer" ItemSize="ItemSize">
                                @RenderOption((context, selectableItem))
                            </Virtualize>
                        }
                        else
                        {
                            foreach (TOption item in Items)
                            {
                                @RenderOption((item, selectableItem))
                            }
                        }
                    }
                </div>

                @if (FooterContent != null)
                {
                    @FooterContent(Items ?? Array.Empty<TOption>())
                }
            </FluentAnchoredRegion>
        }

        @* Tooltip *@
        else if (IsReachedMaxItems && MaximumSelectedOptionsMessage != null)
        {
            <FluentOverlay OnClose="@(e => IsReachedMaxItems = false)" Visible="true" Transparent="true" FullScreen="true" />
            <FluentAnchoredRegion Anchor="@Id"
                                  HorizontalDefaultPosition="HorizontalPosition.Right"
                                  HorizontalInset="true"
                                  VerticalDefaultPosition="@VerticalPosition.Unset"
                                  Style="margin-top: 10px; border-radius: calc(var(--control-corner-radius) * 2px); background-color: var(--neutral-layer-floating); padding: 10px;"
                                  Shadow="ElevationShadow.Flyout">
                @MaximumSelectedOptionsMessage
            </FluentAnchoredRegion>
        }
    </div>
</CascadingValue>

@code {
    private RenderFragment<(TOption Item, string? SelectableItem)> RenderOption => context => __builder =>
    {
        var optionValue = GetOptionValue(context.Item);
        <FluentOption TOption="TOption"
                      @key="@context.Item"
                      Value="@optionValue"
                      Style="@OptionStyle"
                      Class="@OptionClass"
                      Selected="@GetOptionSelected(context.Item)"
                      Disabled="@(GetOptionDisabled(context.Item) ?? false)"
                      OnSelect="@OnSelectCallback(context.Item)"
                      aria-selected="@(GetOptionSelected(context.Item) || optionValue == context.SelectableItem ? "true" : "false")"
                      selectable="@(optionValue == context.SelectableItem)">
            @if (OptionTemplate == null)
            {
                @GetOptionText(context.Item)
            }
            else
            {
                @OptionTemplate(context.Item)
            }
        </FluentOption>
    };

    private RenderFragment RenderSelectedOptions => __builder =>
    {
        if (SelectedOptions != null)
        {
            foreach (var item in SelectedOptions)
            {
                if (SelectedOptionTemplate == null)
                {
                    var text = @GetOptionText(item);

                    if (ReadOnly || Disabled)
                    {
                        <FluentBadge Appearance="@AspNetCore.Components.Appearance.Neutral"
                                     aria-label="@GetOptionText(item)">
                            @text
                        </FluentBadge>
                    }
                    else
                    {
                        <FluentBadge Appearance="@AspNetCore.Components.Appearance.Neutral"
                                     OnDismissClick="@(e => RemoveSelectedItemAsync(item))"
                                     DismissTitle="@(string.Format(AccessibilityRemoveItem, text))"
                                     aria-label="@GetOptionText(item)">
                            @text
                        </FluentBadge>
                    }
                }
                else
                {
                    @SelectedOptionTemplate(item)
                }
            }
        }
    };
}
